/**
 * 表单字段组件
 */
import React, { Component } from 'react';
import { Form, Input, Select, Checkbox, AutoComplete, LocaleProvider,TreeSelect, DatePicker,Spin,Radio,TimePicker } from 'antd';
import { isEmpty ,loadListData,loadTreeListData,ajax, inArray,isNull} from '../common';
import zh_CN from 'antd/lib/locale-provider/zh_CN';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import { getUIList } from '../uiConfig';
import UIIcon from './UIIcon';
import moment from 'moment';

// const MonthPicker = DatePicker.MonthPicker;
const RangePicker = DatePicker.RangePicker;
const { TextArea } = Input;
const FormItem = Form.Item;
const Option = Select.Option;
// const AutoCompleteOption = AutoComplete.Option;
const RadioGroup = Radio.Group;

export default class UIFormField extends Component {
    constructor(props) {
        super(props);
        this.params = props.params;
        if (isEmpty(props.formField.dataSrc) === false) {
            this.state = { optionItems : [],treeData : [], list: getUIList(props.formField.dataSrc), disabled: props.disabled !== null ? props.disabled : {}, disabledValues: props.disabledValues !== null ? props.disabledValues : [] };
        }
        else if(isNull(props.formField.dataList) === false) {
            this.state = { optionItems : [],treeData : [], list: props.formField.dataList, disabled: props.disabled !== null ? props.disabled : {}, disabledValues: props.disabledValues !== null ? props.disabledValues : [] };
        }
        else {
            this.state = { optionItems : [],treeData : [], list: [], disabled: props.disabled !== null ? props.disabled : {}, disabledValues: props.disabledValues !== null ? props.disabledValues : [] };
        }
    }

    componentDidMount(){

        this.updateFormFiled();
    }

    setParams = (params) => {
        this.params = params;
        this.updateFormFiled();
    }

    addOptionItems = (optionItems) => {

        const items = this.state.optionItems;

        const newItems = items.concat(optionItems);

        this.setState({ optionItems : newItems });

    }

    removeOptionItems = (optionValues) => {

        const items = this.state.optionItems;

        const newItems = [];

        items.forEach(item => {
            if(inArray(item.props.value,optionValues) === -1){
                newItems.push(item);
            }
        });

        this.setState({ optionItems : newItems });

    }


    updateFormFiled = () => {

        const {formField,formData} = this.props;

        const { list } = this.state;

        if (formField.type === "list") {

            let optionItems = [];
            if (list.type === "static") {
                optionItems = list.listData.map((data) => {
                    return (<Option key={data.data} value={data.data}>{isEmpty(data.icon) === false ? <UIIcon icon={data.icon} /> : ''}{data.label}</Option>);
                });
                this.setState({optionItems : optionItems});
            }
            else if (isEmpty(list.searchProperty) === false && isEmpty(list.type) === false) {
                optionItems = isNull(this.state[formField.id + 'DataSource']) !== true ? this.state[formField.id + 'DataSource'].map((item) => { return <Option key={item.list.dataProperty}>{item.list.labelProperty}</Option> }) : [];
                this.setState({optionItems : optionItems});
            }
            else if (isEmpty(list.type) === false) {
                
                 loadListData(list.type, list.dataProperty, list.labelProperty, list.iconProperty, isEmpty(list.script) === false ? eval('(' + list.script + ')') : null).then( (items) => {
                    const staticList = list.listData.map((data) => {
                        return (<Option key={data.data} value={isEmpty(formField.dataType) ? data.data : parseInt(data.data,0)}>{isEmpty(data.icon) === false ? <UIIcon icon={data.icon} /> : ''}{data.label}</Option>);
                    });
                    const optList = items.map((item) => <Option key={item.id} value={isEmpty(formField.dataType) ? item.id : parseInt(item.id,0)}>{isEmpty(item.icon) === false ? <UIIcon icon={item.icon} /> : []} {item.text}</Option>);
                    optionItems = staticList.concat(optList);
                    this.setState({optionItems : optionItems});
                } );

            }
        }
        else if(formField.type === "autoComplete" && isEmpty(list.searchProperty) === false && isNull(formData) === false && isNull(formData[formField.id]) === false ){
            const owner = this;
            // console.log(formData);
            // const formFieldDataSource = this.state[formField.id + 'DataSource'];
            let params = {};
            params[list.searchProperty] = formData[formField.id];
            //let script = isEmpty(list.script) === false ? eval('(' + list.script + ')') : {};
            ajax(list.type, {...params}).then((data) => {
                let newArray = [];
                // if (isNull(formFieldDataSource) !== true) {
                //     newArray = newArray.concat(formFieldDataSource);
                //     for (let i = 0; i < data.records.length; i++) {
                //         let founded = false;
                //         for (let j = 0; j < formFieldDataSource.length; j++) {
                //             if (data.records[i][list.dataProperty] === formFieldDataSource[j][list.dataProperty]) {
                //                 founded = true;
                //             }
                //         }
                //         if (founded === false) {
                //             newArray.push(data.records[i]);
                //         }
                //     }
                // }
                // else {
                    newArray = data.records;
                // }
                let state = {};
                state[formField.id + 'DataSource'] = newArray;
                owner.setState(state);
            });
        }
        else if (formField.type === "treeList") {
           
            loadTreeListData(list.type,isEmpty(list.script) === false ? eval('(' + list.script + ')') : null).then( data => {
                this.setState({treeData : data});
            });
        }
        else if(formField.type === "checkBox"){
            let optionItems = [];
            if (list.type === "static") {
                optionItems = list.listData.map((data) => {
                    return { label: data.label, value: data.data }
                });
                this.setState({optionItems : optionItems});
            }
            else if (isEmpty(list.type) === false) {
                
                 loadListData(list.type, list.dataProperty, list.labelProperty, list.iconProperty, isEmpty(list.script) === false ? eval('(' + list.script + ')') : null).then( (items) => {
                    const staticList = list.listData.map((data) => {
                        return { label: data.label, value: isEmpty(formField.dataType) ? data.data : parseInt(data.data,0) }
                    });
                    const optList = items.map((item) => {
                        return { value : (isEmpty(formField.dataType) ? item.id : parseInt(item.id,0)) ,label:item.text}
                    });
                    optionItems = staticList.concat(optList);
                    this.setState({optionItems : optionItems});
                } );

            }
        }
    }

    getFieldItem = (formField,fieldDecoratorOptions,itemLayout) => {

        const { list,optionItems } = this.state;

        const { disabled,fieldRender ,formItemLayout, formData,extendProps} = this.props;

        if (isEmpty(formField.span) === false) {
            itemLayout.wrapperCol.sm.span = formField.span;
        }

        if (formItemLayout !== null) {
            itemLayout = formItemLayout;
        }

        if ((formField.type === "list") && formField.allowNull === false) {
            fieldDecoratorOptions.initialValue = isNull(formData) === false ? (formData[formField.id]) : (optionItems.length > 0 ? optionItems[0].props.value : '');
        }
        else if(formField.type === "radioGroup"){
            fieldDecoratorOptions.initialValue = isNull(formData) === false ? (formData[formField.id]) : (list.listData.length > 0 ? list.listData[0].data : '');
        }
        else if (formField.type === "checkBox") {
            //fieldDecoratorOptions.valuePropName = 'checked';
            fieldDecoratorOptions.initialValue = formData != null ? (formData[formField.id]) : null;
        }
        else if (formField.type === 'dateRange') {
            if (formData !== undefined) {
                fieldDecoratorOptions.initialValue = [formData[formField.id.split('_')[0]] !== null ? moment(formData[formField.id.split('_')[0]], 'YYYY-MM-DD') : null, formData[formField.id.split('_')[1]] !== null ? moment(formData[formField.id.split('_')[1]], 'YYYY-MM-DD') : null];
            }
            else {
                fieldDecoratorOptions.initialValue = [null, null];
            }
        }
        else if (formField.type === 'multiList') {
            fieldDecoratorOptions.initialValue = isNull(formData) !== true ? formData[formField.id] : [];
        }
        else if (formField.type === 'autoComplete') {
            fieldDecoratorOptions.initialValue = isNull(formData) !== true ? formData[formField.id] : null;
        }
        else {
            fieldDecoratorOptions.initialValue = isNull(formData) !== true ? formData[formField.id] : null;
        }

        let checkrules = {
            required: formField.allowNull === false,
            message: '请输入' + formField.title + '!'
        };

        if (formField.type === "dateRange") {
            checkrules.type = 'array';
        }

        fieldDecoratorOptions.rules = [checkrules];

        if(isNull(this.props.initialValue) === false && isNull(fieldDecoratorOptions.initialValue) === true){
            fieldDecoratorOptions.initialValue = this.props.initialValue;
        }


        if (formField.type === "textarea") {
            return (<TextArea rows={2} readOnly={formField.readOnly === true} disabled={disabled} {...extendProps} />);
        }
        else if (formField.type === "list") {
            const canSearch = !isEmpty(formField.desc) && formField.desc.indexOf("[search]") !== -1;
            return (
                <Select disabled={formField.readOnly === true || disabled}
                    allowClear={formField.allowNull !== false}
                    getPopupContainer={trigger => trigger.parentNode}
                    placeholder={formField.tipInfo}
                    showSearch={canSearch}
                    {...extendProps}
                    filterOption={(input, option) => option.props.children[2].toLowerCase().indexOf(input.toLowerCase()) >= 0}
                >
                    {this.state.optionItems}
                </Select>
            );
        }
        else if (formField.type === "treeList") {
            const canSearch = !isEmpty(formField.desc) && formField.desc.indexOf("[search]") !== -1;
            return (
                <TreeSelect disabled={formField.readOnly === true || disabled}
                    getPopupContainer={trigger => trigger.parentNode}
                    allowClear={formField.allowNull !== false}
                    treeData={this.state.treeData}
                    treeNodeFilterProp={canSearch ? 'title':'value'}
                    {...extendProps}
                    showSearch={canSearch}>
                </TreeSelect>
            );
        }
        else if (formField.type === "multiList" || formField.type === "autoComplete") {
            return (
                <Select disabled={formField.readOnly === true || disabled}
                    showSearch={formField.type === "autoComplete"}
                    allowClear={formField.allowNull !== false}
                    placeholder={formField.tipInfo}
                    mode={formField.type === "multiList" && isEmpty(list.searchProperty) === false ? 'multiple' : ''}
                    getPopupContainer={trigger => trigger.parentNode}
                    filterOption={false}
                    notFoundContent={this.state[formField.id + 'Fetching'] ? <Spin size="small"></Spin> : null}
                    onChange={isEmpty(list.searchProperty) ? null : (value) => {
                        let state = {};
                        state[formField.id + 'Fetching'] = false;
                        this.setState(state);
                    }
                    }
                    onSearch={isEmpty(list.searchProperty) ? null : (value) => {
                        const owner = this;
                        const formFieldDataSource = this.state[formField.id + 'DataSource'];
                        let state = {};

                        state[formField.id + 'Fetching'] = true;
                        this.setState(state);
                        let params = {};
                        params[list.searchProperty] = value;
                        //let script = isEmpty(list.script) === false ? eval('(' + list.script + ')') : {};
                        {ajax(list.type, {...params}).then((data) => {
                            let newArray = [];
                            // if (isNull(formFieldDataSource) !== true) {
                            //     newArray = newArray.concat(formFieldDataSource);
                            //     for (let i = 0; i < data.records.length; i++) {
                            //         let founded = false;
                            //         for (let j = 0; j < formFieldDataSource.length; j++) {
                            //             if (data.records[i][list.dataProperty] === formFieldDataSource[j][list.dataProperty]) {
                            //                 founded = true;
                            //             }
                            //         }
                            //         if (founded === false) {
                            //             newArray.push(data.records[i]);
                            //         }
                            //     }
                            // }
                            // else {
                                newArray = data.records;
                            // }
                            let state = {};
                            state[formField.id + 'Fetching'] = false;
                            state[formField.id + 'DataSource'] = newArray;
                            owner.setState(state);
                        });}
                    }}
                    {...extendProps}
                >
                    {isNull(this.state[formField.id + 'DataSource']) !== true ? this.state[formField.id + 'DataSource'].map((item) => { return <Option key={item[list.dataProperty]} value={isEmpty(formField.dataType) ? item[list.dataProperty] : parseInt(item[list.dataProperty],0)} disabled={this.state.disabledValues && this.state.disabledValues.find((value, index, arr) => { return item[list.dataProperty] === value })}>{isEmpty(item[list.iconProperty]) === false ? <UIIcon icon={item[list.iconProperty]} /> : []} {item[list.labelProperty]}</Option> }) : null}
                </Select>
            );
        }
        else if (formField.type === "date") {
            return (
                <DatePicker readOnly={formField.readOnly === true || disabled} placeholder={formField.tipInfo}
                    getPopupContainer={trigger => trigger.parentNode}
                    allowClear={formField.allowNull !== false}
                    {...extendProps}
                />
            );
        }
        else if (formField.type === "dateRange") {
            return (
                
                <RangePicker locale={locale} readOnly={formField.readOnly === true || disabled} placeholder={isEmpty(formField.tipInfo) ? [] : [formField.tipInfo.split('_')[0] != null ? formField.tipInfo.split('_')[0] : '', formField.tipInfo.split('_')[1] != null ? formField.tipInfo.split('_')[1] : '']}
                    getPopupContainer={trigger => trigger.parentNode}
                    allowClear={formField.allowNull !== false}
                    {...extendProps}
                />
                
            );
        }
        else if(formField.type === "timePicker"){
            return (
                <TimePicker
                    placeholder={formField.tipInfo}
                    disabled={formField.readOnly === true || disabled}
                    {...extendProps}
                />
            );
        }
        else if (formField.type === "checkBox") {
           
            return (
                <Checkbox.Group
                    placeholder={formField.tipInfo}
                    disabled={formField.readOnly === true || disabled}
                    options={optionItems}
                    {...extendProps}
                    />
                );
        }
        else if (formField.type === "radioGroup") {
            return (
                <RadioGroup disabled={formField.readOnly === true || disabled} {...extendProps}>
                    {
                        list.listData.map((data) => {
                            return (
                                <Radio key={data.data + "Radio"} value={data.data}>{data.label}</Radio>
                            );
                        })
                    }
                </RadioGroup>
            );
        }
        else if(formField.type === "custom"){
            return (
                isNull(fieldRender) === false ? fieldRender(formField,fieldDecoratorOptions) : <Input type="text" disabled placeholder="请设置字段的渲染器"/>
            );
        }
        else {
            return (
                <Input type={formField.type} disabled={disabled} readOnly={formField.readOnly === true} placeholder={formField.tipInfo} {...extendProps}/>
            );
        }
    }


    render() {

        const { formField} = this.props;

        const fieldDecoratorOptions = {};

        const itemLayout = {
            labelCol: {
                xs: { span: 24 },
                sm: { span: 5 },
            },
            wrapperCol: {
                xs: { span: 24 },
                sm: { span: 18 },
            },
        };
        
        const fieldItem = this.getFieldItem(formField,fieldDecoratorOptions,itemLayout);
             
        return (
            <FormItem {...itemLayout} label={formField.title}>
                {
                    this.props.fieldDecorator(formField.id, fieldDecoratorOptions)(
                            fieldItem
                        )
                }
            </FormItem>
        );
    }
}
